package com.fastloan.safe.mgt.auth.service.impl;

import com.fastloan.safe.core.param.RoleTypeEnum;
import com.fastloan.safe.core.util.ManagerKit;
import com.fastloan.safe.mgt.auth.dao.CmuRoleMapper;
import com.fastloan.safe.mgt.auth.model.CmuRole;
import com.fastloan.safe.mgt.auth.model.CmuRoleFun;
import com.fastloan.safe.mgt.auth.service.CmuRoleFunService;
import com.fastloan.safe.mgt.auth.service.CmuRoleService;
import com.fastloan.safe.mgt.root.model.CmuFun;
import com.fastloan.safe.mgt.root.model.vo.DefFunTreeVo;
import com.fastloan.safe.mgt.root.service.CmDefFunService;
import com.fastloan.safe.mgt.root.service.CmFunService;
import com.fastloan.safe.mgt.user.model.CmuUser;
import com.fastloan.safe.mgt.user.service.CmuUserService;
import com.kawins.base.BaseMapper;
import com.kawins.base.baseabs.BaseServiceImpl;
import com.kawins.shiro.temp.util.ShiroKit;
import com.kawins.supers.tree.Bean2TreeUtil;
import com.kawins.util.colle.ListSortUtil;
import com.kawins.util.colle.ListUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class CmuRoleServiceImpl extends BaseServiceImpl<CmuRole> implements CmuRoleService {

    @Autowired
    private CmuRoleMapper roleMapper;

    @Autowired
    private CmDefFunService defFunService;

    @Autowired
    private CmFunService funService;

    @Autowired
    private CmuRoleFunService roleFunService;

    @Autowired
    private CmuUserService userService;

    @Override
    protected BaseMapper<CmuRole> buildDao() {
        return roleMapper;
    }

    @Override
    public List<String> selectRole(String userId) {
        return roleMapper.selectRole(userId);
    }

    @Override
    public List<DefFunTreeVo> selectAll2Tree() {
        List<DefFunTreeVo> defFunTreeVos = getRoleFunTreeVos();
        return buildTree(defFunTreeVos);
    }


    @Override
    public List<DefFunTreeVo> selectAll2TreeCheck(String roleId) {
        List<DefFunTreeVo> defFunTreeVos = getRoleFunTreeVos();
        List<CmuRoleFun> select = roleFunService.select(new CmuRoleFun().setRoleId(roleId));
        for (DefFunTreeVo defFunTreeVo : defFunTreeVos) {
            for (CmuRoleFun cmuRoleFun : select) {
                if (cmuRoleFun.getDefFunId().equals(defFunTreeVo.getId())) {
                    defFunTreeVo.setCheck(true);
                }
            }
        }
        return buildTree(defFunTreeVos);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertWithFuns(CmuRole cmuRole, String[] funIds) {
        cmuRole.setCreateTime(new Date());
        cmuRole.setCreateBy(ManagerKit.getUserId());
        cmuRole.setIsDef(0);
        cmuRole.setStates(1);
        cmuRole.setTopOrgId(ManagerKit.getTopOrgId());
        insertSelective(cmuRole);
        List<CmuRoleFun> list = new ArrayList<>(funIds.length);
        for (String funId : funIds) {
            list.add(new CmuRoleFun().setRoleId(cmuRole.getId()).setDefFunId(funId));
        }
        roleFunService.insertList(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateWithFuns(CmuRole cmuRole, String[] funIds) {
        cmuRole.setCreateTime(null);
        cmuRole.setCreateBy(null);
        cmuRole.setIsDef(null);
        cmuRole.setTopOrgId(null);
        cmuRole.setStates(null);
        updateByPrimaryKeySelective(cmuRole);
        roleFunService.delete(new CmuRoleFun().setRoleId(cmuRole.getId()));
        List<CmuRoleFun> list = new ArrayList<>(funIds.length);
        for (String funId : funIds) {
            list.add(new CmuRoleFun().setRoleId(cmuRole.getId()).setDefFunId(funId));
        }
        roleFunService.insertList(list);
        clearAuth(cmuRole.getId());
    }

    private void clearAuth(String roleId) {
        List<CmuUser> list = userService.selectByRoleId(roleId, null);
        Set<Object> userNames = ListUtil.listField2Set("username", list);
        for (Object username : userNames) {
            ShiroKit.clearAuthorizationInfo(username.toString());
        }
    }

    @Override
    public List<CmuRole> selectByUserId(String userId) {
        return roleMapper.selectByUserId(userId);
    }

    @Override
    public List<CmuRole> selectByRoleType(RoleTypeEnum roleTypeEnum) {
        return roleMapper.selectByRoleType(ManagerKit.getTopOrgId(), roleTypeEnum.getCode());
    }

    private List<DefFunTreeVo> getRoleFunTreeVos() {
        List<CmuFun> cmuFuns = funService.select(new CmuFun().setTopOrgId(ManagerKit.getTopOrgId()));
        List<DefFunTreeVo> list = new ArrayList<>(0);
        for (int i = 0; i < cmuFuns.size(); i++) {
            if (i == 0) {
                list.addAll(defFunService.selectAllSonByTop(cmuFuns.get(i).getDefFunId(), true));
                continue;
            }
            list.addAll(defFunService.selectAllSonByTop(cmuFuns.get(i).getDefFunId(), false));
        }
        return list;
    }

    private List<DefFunTreeVo> buildTree(List<DefFunTreeVo> defFunTreeVos) {
        LinkedHashMap<String, Integer> orderMap = new LinkedHashMap<>();
        orderMap.put("shorts", ListSortUtil.ASC);
        Bean2TreeUtil<DefFunTreeVo> bean2TreeUtil = new Bean2TreeUtil<>(orderMap);
        return bean2TreeUtil.getChildNodesByParentId(defFunTreeVos, CmDefFunService.TOP_FUN_PARENT_ID);
    }
}
